<?php
/*
 +----------------------------------------------------------------------
 + Title        : Where 控制器
 + Author       : Randy_chen
 + Version      : V1.0.0.1
 + Initial-Time : 2019/5/27 8:33
 + Last-time    : 2019/5/27 8:33+ 86187
 + Desc         : Where
 +----------------------------------------------------------------------
*/


namespace app\common\lib;

use think\facade\Request;

class Where
{
    protected $where = [];
    protected $order = [];
    protected $fields = [];
    protected $limit = 0;
    protected $page = false;

    /**
     * @return array
     */
    public function getWhere(): array
    {
        return $this->where;
    }

    /**
     * @return array
     */
    public function getOrder(): array
    {
        return $this->order;
    }

    /**
     * @return string
     */
    public function getLimit()
    : string
    {
        return $this->limit;
    }

    /**
     * @Desc:
     * @return bool
     *
     *
     * @User: Randy_chen
     * @Date: 2019/6/9
     * @Time: 15:27
     */
    public function getPage(): bool
    {
        return $this->page;
    }


    /**
     * 设置Like查询条件
     *
     * @param string|array $fields 查询字段
     * @param string       $input  输入类型 get|post
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function like($fields, $input = 'request', $alias = '#')
    {
        $data = Request::$input();
        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                $field
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }
            if (isset($data[$qk]) && $data[$qk] !== '') {
                $this->where[] = [
                    $dk,
                    'LIKE',
                    "%{$data[$qk]}%"
                ];
            }
        }
        return $this;
    }

    /**
     * 设置Equal查询条件
     *
     * @param string|array $fields 查询字段
     * @param string|array       $input  输入类型 get|post
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function equal($fields, $input = 'param', $alias = '#')
    {
        $data =  is_array($input) ? $input :  Request::$input();

        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                ''
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }

            if (isset($data[$dk]) && $data[$dk] !== '') {
                if ($qk) {
                    $this->where[] = [
                        $qk . '.' . $dk,
                        '=',
                        "{$data[$dk]}"
                    ];
                } else {
                    $this->where[] = [
                        $dk,
                        '=',
                        "{$data[$dk]}"
                    ];
                }
            }
        }
        return $this;
    }

    /**
     * 设置Equal查询条件
     *
     * @param string|array $fields 查询字段
     * @param string|array       $input  输入类型 get|post
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function lt($fields, $input = 'param', $alias = '#')
    {
        $data =  is_array($input) ? $input :  Request::$input();

        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                ''
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }

            if (isset($data[$dk]) && $data[$dk] !== '') {
                if ($qk) {
                    $this->where[] = [
                        $qk . '.' . $dk,
                        '<',
                        "{$data[$dk]}"
                    ];
                } else {
                    $this->where[] = [
                        $dk,
                        '<',
                        "{$data[$dk]}"
                    ];
                }
            }
        }
        return $this;
    }


    /**
     * 设置Equal查询条件
     *
     * @param string|array $fields 查询字段
     * @param string|array       $input  输入类型 get|post
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function gt($fields, $input = 'param', $alias = '#')
    {
        $data =  is_array($input) ? $input :  Request::$input();

        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                ''
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }

            if (isset($data[$dk]) && $data[$dk] !== '') {
                if ($qk) {
                    $this->where[] = [
                        $qk . '.' . $dk,
                        '>',
                        "{$data[$dk]}"
                    ];
                } else {
                    $this->where[] = [
                        $dk,
                        '>',
                        "{$data[$dk]}"
                    ];
                }
            }
        }
        return $this;
    }


    /**
     * 设置IN区间查询
     *
     * @param string $fields 查询字段
     * @param string $split  输入分隔符
     * @param string $input  输入类型 get|post
     * @param string $alias  别名分割符
     *
     * @return $this
     */
    public function in($fields, $split = ',', $input = 'param', $alias = '#')
    {
        $data = Request::$input();
        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                $field
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }

            if (isset($data[$dk]) && $data[$dk] !== '') {
                if ($qk) {
                    $this->where[] = [
                        $qk . '.' . $dk,
                        'IN',
                        explode($split, $data[$qk])
                    ];
                } else {
                    $this->where[] = [
                        $dk,
                        'IN',
                        explode($split, $data[$qk])
                    ];
                }
            }
        }
        return $this;
    }

    /**
     * 设置内容区间查询
     *
     * @param string|array $fields 查询字段
     * @param string       $split  输入分隔符
     * @param string       $input  输入类型 get|post
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function valueBetween($fields, $split = ' ', $input = 'param', $alias = '#')
    {

        return $this->setBetweenWhere($fields, $split, $input, $alias);
    }


    /**
     * 设置日期时间区间查询
     *
     * @param string|array $fields 查询字段
     * @param string       $split  输入分隔符
     * @param string       $input  输入类型
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function dateBetween($fields, $split = ' - ', $input = 'param', $alias = '#')
    {
        return $this->setBetweenWhere($fields, $split, $input, $alias, function ($value, $type) {
            if ($type === 'after') {
                return "{$value} 23:59:59";
            } else {
                return "{$value} 00:00:00";
            }
        });
    }

    /**
     * 设置时间戳区间查询
     *
     * @param string|array $fields 查询字段
     * @param string       $split  输入分隔符
     * @param string       $input  输入类型
     * @param string       $alias  别名分割符
     *
     * @return $this
     */
    public function timeBetween($fields, $split = ' - ', $input = 'param', $alias = '#')
    {
        return $this->setBetweenWhere($fields, $split, $input, $alias, function ($value, $type) {
            if ($type === 'after') {
                return strtotime("{$value} 23:59:59");
            } else {
                return strtotime("{$value} 00:00:00");
            }
        });
    }


    /**
     * 设置区域查询条件
     *
     * @param string|array $fields 查询字段
     * @param string       $split  输入分隔符
     * @param string       $input  输入类型
     * @param string       $alias  别名分割符
     * @param callable     $callback
     *
     * @return $this
     */
    private function setBetweenWhere($fields, $split = ' ', $input = 'param', $alias = '#', $callback = null)
    {
        $data = is_array($input)? $input : Request::$input();

        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                ''
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }
            if (isset($data[$dk]) && $data[$dk] ) {
                list($begin, $after) = explode($split, $data[$dk]);
                if (is_callable($callback)) {
                    $after = call_user_func($callback, $after, 'after');
                    $begin = call_user_func($callback, $begin, 'begin');
                }
                $this->where[] = [
                    $qk ?$qk.'.'.$dk : $dk,
                    'between',
                    [
                        $begin,
                        $after
                    ]
                ];
            }
        }
        return $this;
    }

    public function setOrder($fields, $split = ',')
    {
        $order = explode($split, $fields);
        $this->order = array_merge($this->order, $order);
        return $this;
    }

    public function setLimit($limit)
    {
        $this->limit = $limit;
        return $this;
    }

    /**
     * 设置读取字段
     *
     * @param        $fields
     * @param string $alias
     *
     * @return $this
     *
     *
     * @author : Randy_chen
     * @Date   : 2019/7/5
     * @Time   : 21:08
     */
    public function setField($fields, $alias = '#')
    {

        foreach (is_array($fields) ? $fields : explode(',', $fields) as $field) {
            list($dk, $qk) = [
                $field,
                ''
            ];
            if (stripos($field, $alias) !== false) {
                list($dk, $qk) = explode($alias, $field);
            }
            if ($qk) {
                $this->fields[] = [$qk . '.' . $dk];
            } else {
                $this->fields[] = [$dk];
            }
        }
        return $this;
    }
}